<script lang="ts">
  import WidgetColumnBar from './WidgetColumnBar.svelte';
  import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';

  import AppObjectList from '../appobj/AppObjectList.svelte';
  import * as cloudContentAppObject from '../appobj/CloudContentAppObject.svelte';
  import { useCloudContentList, usePublicCloudFiles, useServerStatus } from '../utility/metadataLoaders';
  import { _t } from '../translations';

  import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
  import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
  import SearchInput from '../elements/SearchInput.svelte';
  import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
  import InlineButton from '../buttons/InlineButton.svelte';
  import FontIcon from '../icons/FontIcon.svelte';
  import { apiCall } from '../utility/api';
  import {
    cloudConnectionsStore,
    cloudSigninTokenHolder,
    currentDatabase,
    expandedConnections,
    openedConnections,
    openedSingleDatabaseConnections,
  } from '../stores';
  import _ from 'lodash';
  import { plusExpandIcon } from '../icons/expandIcons';
  import { volatileConnectionMapStore } from '../utility/api';
  import SubCloudItemsList from '../appobj/SubCloudItemsList.svelte';
  import DatabaseWidgetDetailContent from './DatabaseWidgetDetailContent.svelte';
  import { onMount } from 'svelte';
  import DropDownButton from '../buttons/DropDownButton.svelte';
  import { showModal } from '../modals/modalTools';
  import InputTextModal from '../modals/InputTextModal.svelte';
  import ConfirmModal from '../modals/ConfirmModal.svelte';
  import { showSnackbarInfo } from '../utility/snackbar';
  import { isProApp } from '../utility/proTools';
  import { useCloudContentColorFactory, useConnectionColorFactory } from '../utility/useConnectionColor';
  import ErrorInfo from '../elements/ErrorInfo.svelte';
  import FormStyledButton from '../buttons/FormStyledButton.svelte';
  import runCommand from '../commands/runCommand';
  import SaveFileModal from '../modals/SaveFileModal.svelte';
  import newQuery from '../query/newQuery';
  import ConfigureSharedFolderModal from '../modals/ConfigureSharedFolderModal.svelte';

  let filter = '';
  let domSqlObjectList = null;

  const cloudContentList = useCloudContentList();
  const serverStatus = useServerStatus();
  const cloudContentColorFactory = useCloudContentColorFactory(3);
  const connectionColorFactory = useConnectionColorFactory(3);

  $: emptyCloudContent = ($cloudContentList || []).filter(x => !x.items?.length).map(x => x.folid);
  $: cloudContentFlat = _.sortBy(
    ($cloudContentList || [])
      .flatMap(fld => fld.items ?? [])
      .map(data => {
        if (data.type == 'connection') {
          const conid = `cloud://${data.folid}/${data.cntid}`;
          const status = $serverStatus ? $serverStatus[$volatileConnectionMapStore[conid] || conid] : undefined;

          return {
            ...data,
            conid,
            status,
          };
        }

        return data;
      }),
    'name'
  );
  $: contentGroupMap = _.keyBy($cloudContentList || [], x => x.folid);
  $: privateFolderId = $cloudContentList?.find(x => x.isPrivate)?.folid;

  // $: console.log('cloudContentFlat', cloudContentFlat);
  // $: console.log('contentGroupMap', contentGroupMap);

  async function handleRefreshContent() {
    await apiCall('cloud/refresh-content');
  }

  // async function loadCloudConnection(conid) {
  //   const conn = await apiCall('connections/get', { conid });
  //   $cloudConnectionsStore = {
  //     ...$cloudConnectionsStore,
  //     [conid]: conn,
  //   };
  // }

  // function ensureCloudConnectionsLoaded(...conids) {
  //   _.uniq(conids).forEach(conid => {
  //     if (conid?.startsWith('cloud://') && !$cloudConnectionsStore[conid]) {
  //       loadCloudConnection(conid);
  //     }
  //   });
  // }

  // $: ensureCloudConnectionsLoaded(
  //   $currentDatabase?.connection?._id,
  //   ...$openedSingleDatabaseConnections,
  //   ...$openedConnections
  // );

  // onMount(() => {
  //   const currentConid = $currentDatabase?.connection?._id;
  //   if (currentConid?.startsWith('cloud://') && !$cloudConnectionsStore[currentConid]) {
  //     loadCloudConnection(currentConid);
  //   }
  // });

  function createAddItemMenu() {
    return [
      {
        command: 'new.connectionOnCloud',
      },
      {
        text: _t('privateCloudWidget.newSqlScript', { defaultMessage: 'New SQL script' }),
        onClick: () => {
          const data = '';
          showModal(SaveFileModal, {
            data,
            skipLocal: true,
            folid: privateFolderId,
            folder: 'sql',
            onSave: (name, { savedFile, savedFolder, savedFilePath, savedCloudFolderId, savedCloudContentId }) => {
              newQuery({
                // @ts-ignore
                savedFolder: 'sql',
                savedFormat: 'text',
                savedFile,
                savedCloudFolderId,
                savedCloudContentId,

                fixCurrentConnection: true,
                title: savedFile,
              });
            },
          });
        },
      },
    ];
  }

  function createAddFolderMenu() {
    return [
      isProApp() && {
        text: _t('privateCloudWidget.createSharedFolder', { defaultMessage: 'Create shared folder' }),
        onClick: () => {
          showModal(InputTextModal, {
            label: _t('privateCloudWidget.newFolderName', { defaultMessage: 'New folder name' }),
            header: _t('privateCloudWidget.newSharedFolder', { defaultMessage: 'New shared folder' }),
            onConfirm: async newFolder => {
              apiCall('cloud/create-folder', {
                name: newFolder,
              });
            },
          });
        },
      },
      {
        text: _t('privateCloudWidget.addExistingFolder', { defaultMessage: 'Add existing folder (from link)' }),
        onClick: () => {
          showModal(InputTextModal, {
            label: _t('privateCloudWidget.yourInviteLink', { defaultMessage: 'Your invite link (in form dbgate://folder/xxx)' }),
            header: _t('privateCloudWidget.addExistingSharedFolder', { defaultMessage: 'Add existing shared folder' }),
            onConfirm: async newFolder => {
              apiCall('cloud/grant-folder', {
                inviteLink: newFolder,
              });
            },
          });
        },
      },
    ];
  }

  function createGroupContextMenu(folder) {
    const handleRename = () => {
      showModal(InputTextModal, {
        value: contentGroupMap[folder]?.name,
        label: _t('privateCloudWidget.newFolderName', { defaultMessage: 'New folder name' }),
        header: _t('privateCloudWidget.renameFolder', { defaultMessage: 'Rename folder' }),
        onConfirm: async name => {
          apiCall('cloud/rename-folder', {
            folid: folder,
            name,
          });
        },
      });
    };

    const handleDelete = () => {
      showModal(ConfirmModal, {
        message: _t('privateCloudWidget.deleteFolderConfirm', { defaultMessage: 'Really delete folder {folder}? All folder content will be deleted!', values: { folder: contentGroupMap[folder]?.name } }),
        header: _t('privateCloudWidget.deleteFolder', { defaultMessage: 'Delete folder' }),
        onConfirm: () => {
          apiCall('cloud/delete-folder', {
            folid: folder,
          });
        },
      });
    };

    return [
      contentGroupMap[folder]?.role == 'admin' && [
        { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
        { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
      ],
      isProApp() &&
        contentGroupMap[folder]?.role == 'admin' &&
        !contentGroupMap[folder]?.isPrivate && {
          text: _t('privateCloudWidget.administrateAccess', { defaultMessage: 'Administrate access' }),
          onClick: () => {
            showModal(ConfigureSharedFolderModal, {
              folid: folder,
              name: contentGroupMap[folder]?.name,
            });
          },
        },
      // contentGroupMap[folder]?.role == 'admin' &&
      //   !contentGroupMap[folder]?.isPrivate && {
      //     text: 'Copy invite link',
      //     submenu: [
      //       {
      //         text: 'Admin',
      //         onClick: () => handleCopyInviteLink('admin'),
      //       },
      //       {
      //         text: 'Write',
      //         onClick: () => handleCopyInviteLink('write'),
      //       },
      //       {
      //         text: 'Read',
      //         onClick: () => handleCopyInviteLink('read'),
      //       },
      //     ],
      //   },
    ];
  }
</script>

<WidgetColumnBar>
  <WidgetColumnBarItem
    title="DbGate Cloud"
    name="privateCloud"
    height="50%"
    storageName="privateCloudItems"
    skip={!$cloudSigninTokenHolder}
  >
    <SearchBoxWrapper>
      <SearchInput placeholder={_t('privateCloudWidget.searchPlaceholder', { defaultMessage: 'Search cloud connections and files' })} bind:value={filter} />
      <CloseSearchButton bind:filter />
      <DropDownButton icon="icon plus-thick" menu={createAddItemMenu} title={_t('privateCloudWidget.addNewConnectionOrFile', { defaultMessage: 'Add new connection or file' })} />
      <DropDownButton icon="icon add-folder" menu={createAddFolderMenu} title={_t('privateCloudWidget.addNewFolder', { defaultMessage: 'Add new folder' })} />
      <InlineButton
        on:click={handleRefreshContent}
        title={_t('privateCloudWidget.refreshFiles', { defaultMessage: 'Refresh files' })}
        data-testid="CloudItemsWidget_buttonRefreshContent"
      >
        <FontIcon icon="icon refresh" />
      </InlineButton>
    </SearchBoxWrapper>
    <WidgetsInnerContainer>
      <AppObjectList
        list={cloudContentFlat || []}
        module={cloudContentAppObject}
        emptyGroupNames={emptyCloudContent}
        groupFunc={data => data.folid}
        mapGroupTitle={folid => `${contentGroupMap[folid]?.name} - ${contentGroupMap[folid]?.role}`}
        {filter}
        subItemsComponent={() => SubCloudItemsList}
        expandIconFunc={plusExpandIcon}
        isExpandable={data =>
          data.conid &&
          $cloudConnectionsStore[data.conid] &&
          !$cloudConnectionsStore[data.conid].singleDatabase &&
          $openedConnections.includes(data.conid)}
        getIsExpanded={data => $expandedConnections.includes(data.conid)}
        setIsExpanded={(data, value) => {
          expandedConnections.update(old => (value ? [...old, data.conid] : old.filter(x => x != data.conid)));
        }}
        passProps={{
          onFocusSqlObjectList: () => domSqlObjectList.focus(),
          cloudContentColorFactory: $cloudContentColorFactory,
          connectionColorFactory: $connectionColorFactory,
        }}
        groupContextMenu={createGroupContextMenu}
      />

      {#if !cloudContentFlat?.length}
        <ErrorInfo message={_t('privateCloudWidget.noContent', { defaultMessage: 'You have no content on DbGate cloud' })} icon="img info" />
        <div class="error-info">
          <div class="m-1"></div>
          <FormStyledButton
            value={_t('privateCloudWidget.createConnection', { defaultMessage: 'Create connection on DbGate Cloud' })}
            skipWidth
            on:click={() => {
              runCommand('new.connectionOnCloud');
            }}
          />
        </div>
      {/if}
    </WidgetsInnerContainer>
  </WidgetColumnBarItem>

  <DatabaseWidgetDetailContent bind:domSqlObjectList showCloudConnection={true} />
</WidgetColumnBar>

<style>
  .error-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    margin-top: 10px;
  }
</style>
